L1540.TXT/M.A.L./13.03.2003

This is the 2nd (and, if there is no serious bug, last) release of L1540.

Intro
=====
L1540 is a 25KB SysRPL library for the HP39/40. It provides a number of
functions and commands that can be used in the HOME view, in function
definitions, in programs, and in the HP40G CAS. The functions essentially
comprise much of what makes the difference between an HP40 and an HP49, plus
some more:

Base conversions, bit operations, physical constants, unit conversions, time
and date functions, calendar, time value of money, probability functions,
vector plot and matrix slope plot, multidimensional optimization, discrete
Fourier transform, numerical solution of differential equation systems,
support to use programs as functions and support for local variables in
programs, a few functions for electrical engineering, and a few system
utilities.

The source is included and compiles with the HP DOS tools.


Important
=========
1. This is a _library_, not an aplet (and not a program), but contrary to
   the first release a self-delete command is included (thanks to Jordi
   Hidalgo for the idea and the code). There is no user command to copy the
   lib directly to another HP39/40G.

2. The library does not affect normal calculator operations, but, of course,
   the letter sequences that make up the new command names are now
   interpreted as command names, not as variables that are to be
   (implicitly) multiplied.

3. The library has been tested but is sufficiently complex to make sure that
   any testing is incomplete (thanks to Axel Bodemann for some support
   here). Therefore any usage of this library is at the user's own risk.

4. The library is freely distributable as long as it is not sold for money,
   per se or bundled with anything else.


Download
========
I'm using Kermit on a DOS-PC and know nothing about other comm programs.
With Kermit (available for free from the WWW) the procedure is as follows:

1. Connect the HP39/40G with the serial port of the PC.

2. On the PC: execute kermit.exe while all the files of this archive are
   present. The kermit server should come up.

3. On the HP39/40G: do program receive, disk drive OK, other.. OK, type
   L1540, OK.

4. After a few minutes, the download should be finished and the program
   catalog reappears. Go to the HOME screen and try the following.


Usage
=====
The built-in help command is AA (some users had problems with the XX in the
1st release). Type AA and ENTER. A choose list with a micro-syntax
description for all commands appears. Select the desired command to see a
more detailed description. On exit, a mini-syntax is returned to the HOME
screen, which may be copied to the command line for editing. SYNTAX
also works, but is less informative.


Remarks on some Commands
========================
1. All date and time functions expect/return the European date and time
   format, dd.mmyyyy rsp. hh.mmss.

2. The full screen paging calendar CA(0) or CA(date) uses the German day and
   month abbreviations (some of which coincide with the English ones), and
   the weeks start on Monday. It should still be easily comprehensible
   without any knowledge of German. The number after the year in the upper
   left is the day number of the first day of the month shown, within the
   current year. The numbers in the leftmost column are the week numbers
   within the year.

3. Some functions are of the form FCT({x1,x2,...,xn},k). This means the
   underlying formula has n variables, and the user wants to solve for the
   k'th one. For this, all xi must have the desired values, and xk may have
   any value and will be ignored. All such functions are solved
   analytically, not with a numeric solver. The single exception is solving
   for the interest rate in the TVM formula.

4. In TVM calculations, I is the interest rate per period. If the interest
   per year is 5%, and the period of payments is a month, the interest per
   period that must be used is 0.05/12.

5. Base Conversions: DH(dec) returns a list with the hexadecimal, octal, and
   binary representration of dec to the stack (the display). These list
   elements cannot be used in further calculations. HD prompts for a hex
   number with a special input form (no need to press ALPHA before entering
   a letter). BC converts between decimal and arbitrary bases and vice
   versa, where numbers in these bases are represented as lists of decimals.
   E.g., BC(6,2) returns {1,1,0}, the binary representation of 6.
   Conversely, BC({1,1,0},2) returns 6.

6. Bit operations: The wordsize is internally fixed to 32bit. Externally all
   numbers are decimal. These operations are interbally string-based and
   therefore quite slow. The operations are quite flexible, thus the
   syntax is somewhat complicated:

   BIT(x,n,p) performs operations on the single bit n within x, depending
     on p:
     p=-1: bit n is toggled
     p= 0: bit n is cleared (set to 0)
     p= 1: bit n is set (to 1)
     p= 2: bit n is not changed (only tested).
     In any case, the function returns the (new) value of bit n.
     Index n=0 refers to the LSB, n=31 refers to the MSB.

   BCNT(x,p) does some special operations depending on p:
     p=0: returns the value of the LSB, which is 1 for an odd number x,
          0 for an even number.
     p=1: returns the number of bits set
     p=2: returns the index of the MSB, or -1 if no bit is set.

   BSL(x,n,p) shifts x by n bits (left for n>0, right for n<0).
     The bit that in pulled into the 'empty' bit depends on p:
     p=-1: the LSB (for left shift) or MSB (for right shift)
     p= 0: a 0 bit
     p= 1: a 1 bit
     p= 2: the bit that has been shifted out on the other side
           (this means, a rotate operation is performed)

     n=0 is a special case:
     p=0: all bits are toggled (a NOT or complement operation)
     p=1: the bits are mirrored, i.e, the LSB becomes the MSB and vice
          versa, etc.

   BOP(x,y,p) performs a bitwise operation on x and y depending on p:
     p=-1: returns x XOR y
     p= 0: returns x AND y
     p= 1: returns x OR y
   
7. CV(n) just returns a factor for unit conversions. E.g., to convert 5
   inches to meters do 5*CV(0) (interactive) or 5*CV(4). To convert 5 meters
   to inches, do 5/CV(0) or 5/CV(4).

8. The physical constants CO(n) are not those (partially outdated ones) from
   the HP48/49, but those of 2000. For practical purposes, this make no
   significant difference. Only SI units are used.

9. Probability functions: The three functions BINO, BINOR, SAMC answer most
   questions of the "what is the probability of ..." type. Incidentally,
   SAMC also answers the famous question of how many people are needed to
   have two with the same birthday with probability 1/2:
   SAMC(23,365,2) = 0.5, so it is only 23.

10. Graphics: MBP quickly plots a vector of up to 131 values (rsp. the first
    131 values of longer vectors) with autoscaling. MSP plots a
    two-dimensional matrix, where each value determines the slope of a
    straight line on the screen. With some imagination, this is also a
    replacement for a wireframe or similar 3D-plot (and actually more
    appropriate for a small calc screen).

11. Programs as functions: Normally programs cannot be included in algebraic
    (function) expressions and cannot be invoked with parameters. The
    functions PR and PS allow to do such things for the (small) price of a
    naming convention: The program name must start with a capital P and
    continue with a number, like P1, P4321, etc. The number part is the
    1st argument to PR and PS. The 2nd argument is an arbitrary object which
    will be passed, in the Ans variable, to the program. The program output
    is also expected in Ans.
    
    This means, that Ans\>... and ...\>Ans must be the first and last
    actions in such a program, otherwise Ans might be invalid.
    
    Example: a function, say P99, that returns the sum of two numbers:
    P99: Ans\>L1:L1(1)+L1(2)\>Ans
    Now PR(99,{3,4}) will return 7.

    PR and PS should only be used in HOME and in programs, but not in, e.g.,
    plot function definitions. The environment the calc runs programs in is
    not compatible with these. To 'plot a program', use something like
    MBP(PSRA(...)), to find the 'zeros of a program', use PSROOT.

12. Local variables: PS saves and restores the variables A..Z, so these are
    local in the program and keep their original values upon program
    termination (but not if the program has a bug, causing early
    termination!). The functions PUSHL and POPL can be used to make other
    variables local, too: on program entry, push them, on program exit, pop
    them. L0 is internally used to hold the variables temporarily. Of
    course, the pop action will again overwrite Ans. Therefore PUSHR and
    POPR are provided to save Ans (or any other object) temporarily, from
    the other side of L0.

    Example: as above, but L1 shall be local:
                                @ L0         action
                                @ {...}
    P99: PUSHL(L1):             @ {L1...}    save L1
         Ans\>L1:               @ {L1...}    get the function argument
         L1(1)+L1(2)\>Ans       @ {L1...}    calculate the function result
         PUSHR(Ans):            @ {L1...Ans} save the result
         POPL\>L1:              @ {...Ans}   restore L1, overwriting Ans
         POPR                   @ {...}      restore the result in Ans

13. Flags: Like the HP49, the HP40 has 128 user flags and 128 system flags.
    SF makes these accessible. The system flags should not be messed with.
    Each user flag can store a boolean value, 0 or 1, so A..Z need not
    be wasted for that.

14. DEQ solves single and systems of 1st order differential equations
    numerically. Examples:

    Ex.: Solve y'=x+y in x=0..1, y(0) = 0
    Sol: P99: Ans\>L1:L1(2)\>M1:[L1(1)+M1(1)]\>Ans
         DEQ(99,0,1,.1,[0])\>M2 yields an end value of y(1)=0.718279...
         correct is 0.718281.., from y(x) = exp(x)-x-1
         => with 0.1 steps here accurate to 0.00001

    Ex.: Solve y''=2y'^2y^3 in x=0..1,y(0)=1,y'(0)=-1
    Sol: P88: Ans\>L1:L1(2)\>M1:[M1(2),2*(M1(2)^2/M1(1)-M1(1)^2)]\>Ans
         Subst y1' = y2, y2'=2y2^2/y1-2y1^2
         DEQ(88,0,1,.1,[1,-1])\>M2 yields end values [0.333,-0.333]
         correct is y(x)=1/(x^2+x+1) => precise soln.

    See the math literature (or the HP48 user's guide) on how to convert
    higher order diff. eqs. to a system of single order ones (as has been
    done in the last example).

    The algorithm is a 4th order Runge-Kutta with fixed step size. If it
    takes to long, press . (the decimal dot key). To be sure about the
    accuracy, different stepwidth may be tried to see if they lead to
    the approximately same end value.

15. Nonlinear Optimization with NLOP: Finds the minimum of a one- or
    multidimensional function, more precisely the minimum which is closest
    to the starting point. There is no guarantee to find the _global_
    minimum (and no algorithm exists that is guaranteed to find it in a
    finite time).

    Try the famous Rosenbrock test function, which converges particularly
    slow (takes a few minutes):
    P77: Ans\>M1:100*(M1(2)-M1(1)^2)^2+(1-M1(1))^2\>Ans
    NLOP(77,.1,.001,100,[0,0])->{1,0.00001,[0.99..,0.99..]}.
    The exact solution is f([1,1])=0.

    Here the initial step width is 0.1, the terminating step width 0.001,
    and the maximum number of iterations is 100. The algorithm stops when
    the minimum step width or the maximum number of iterations is reached,
    whichever occurs earlier. The latter case is indicated by a result
    {0,...} It it takes too long, press . (the decimal dot key). To be sure
    about the 'globalness' of a minimum, different starting vectors may be
    tried.

    Restrictions on the variables can be introduced with penalty functions
    that transform the variables. Example: For the condition x >= a, use the
    transformation x = a+y^2.

    The Hooke-Jeeves algorithm used here is simple and fast (yet still slow
    on a pocket calculator). It fails if more than one variable must be
    changed per step to minimize the function further.

16. The keyboard debounce of the HP39/40 is too conservative, i.e. keys go
    lost if pressed in a fast sequence. The factory value is KEYTIME(1365).
    With KEYTIME(400) debouncing becomes faster than very fast typing, but
    is still effective (on _my_ HP40).

17. UHR (German for clock) is a kind of wrist watch replacement:
    Executing UHR turns off the calc. From now on the ON key toggles between
    calc off and a display of the current date and time. To exit from this
    loop, press a key different from ON (like ENTER) when the calc is on.
    Sounds more complicated than it is.

To get to know all commands, browse through the AA help function. If the
help text seems obscure (no room for verbose explanations), try the command.


Not implemented
===============
- String operations. Will be in a different lib later, this one is big
  enough now.

- Interrupt-based alarm. Not sure if the OS allows this. Seems it does not
  even know about the user interrupts the other HP4x calcs have.


Bug Reports to
==============
martin.lang@biotronik-erlangen.de

--- End ---
